//
// Created by Administrator on 2021/4/12.
//

/*
给定两个二叉树，想象当你将它们中的一个覆盖到另一个上时，两个二叉树的一些节点便会重叠。

你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠，那么将他们的值相加作为节点合并后的新值，否则不为NULL 的节点将直接作为新二叉树的节点。

示例1:

输入:
Tree 1                     Tree 2
1                         2
/ \                       / \
        3   2                     1   3
/                           \   \
      5                             4   7
输出:
合并后的树:
3
/ \
	   4   5
/ \   \
	 5   4   7
注意:合并必须从两个树的根节点开始。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/merge-two-binary-trees
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。*/

#include <string>
#include <iostream>
#include <vector>

using namespace std;

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;

    explicit TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}

    TreeNode(int x, TreeNode *l, TreeNode *r) : val(x), left(l), right(r) {}
};

void preorder(TreeNode *root, vector<int> &res) {
    if (root == nullptr) {
        return;
    }
    res.push_back(root->val);
    preorder(root->left, res); // 对左子节点递归调用
    preorder(root->right, res); // 对右子节点递归调用
}

vector<int> preorderTraversal(TreeNode *root) {
    vector<int> res; // 结果向量
    preorder(root, res);
    return res;
}

class Solution {
public:
    TreeNode *mergeTrees(TreeNode *root1, TreeNode *root2) {
        if (root1 == nullptr and root2 == nullptr) {
            return nullptr;
        }
        if (root1 == nullptr) {
            auto t = new TreeNode(root2->val);
            t->left = root2->left;
            t->right = root2->right;
            return t;
        }
        if (root2 == nullptr) {
            auto t = new TreeNode(root1->val);
            t->left = root1->left;
            t->right = root1->right;
            return t;
        } else {
            auto t = new TreeNode(root1->val + root2->val);
            t->left = mergeTrees(root1->left, root2->left);
            t->right = mergeTrees(root1->right, root2->right);
            return t;
        }
    }
};

class Solution2 { // 题解
public:
    TreeNode *mergeTrees(TreeNode *t1, TreeNode *t2) {
        if (t1 == nullptr) {
            return t2;
        }
        if (t2 == nullptr) {
            return t1;
        }
        auto merged = new TreeNode(t1->val + t2->val);
        merged->left = mergeTrees(t1->left, t2->left);
        merged->right = mergeTrees(t1->right, t2->right);
        return merged;
    }
};


int main() {
    auto t4 = TreeNode(5);
    auto t3 = TreeNode(2);
    auto t2 = TreeNode(3, &t4, nullptr);
    auto t1 = TreeNode(1, &t2, &t3);

    auto n5 = TreeNode(7);
    auto n4 = TreeNode(4);
    auto n3 = TreeNode(3, nullptr, &n5);
    auto n2 = TreeNode(1, nullptr, &n4);
    auto n1 = TreeNode(2, &n2, &n3);

    Solution2 sol;
    auto ans = sol.mergeTrees(&t1, &n1);
    vector<int> v;
    v = preorderTraversal(ans);
    for (auto &x:v) {
        cout << x << endl;
    }
    return 0;
}